﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Extention.ENode.Rpc.Runtime.Client;
using Extention.ENode.Rpc.Runtime.Communally.Convertibles;
using Microsoft.Extensions.DependencyInjection;

namespace Extention.ENode.Rpc.Proxy.Impl
{
    /// <summary>
    /// 默认的服务代理工厂实现
    /// </summary>
    public class ServiceProxyFactory : IServiceProxyFactory
    {
        private readonly IRemoteInvokeService _remoteInvokeService;
        private readonly ITypeConvertibleService _typeConvertibleService;

        public ServiceProxyFactory(IRemoteInvokeService remoteInvokeService, ITypeConvertibleService typeConvertibleService)
        {
            _remoteInvokeService = remoteInvokeService;
            _typeConvertibleService = typeConvertibleService;
        }


        /// <summary>
        /// 创建服务代理
        /// </summary>
        /// <param name="proxyType">代理类型</param>
        /// <returns>服务代理实例</returns>
        public object CreateProxy(Type proxyType, ServiceProvider provider)
        {
            try
            {
                var iType = provider.GetService(proxyType);
                if (iType == null)
                {
                    var proxyTypeI = proxyType
                                  .GetTypeInfo()
                                  .GetConstructors()
                                  .First()
                                  .Invoke(
                                      new object[] { _remoteInvokeService, _typeConvertibleService }
                                  );
                    
                    return proxyTypeI;
                }
                return iType;
            }
            catch (Exception ex)
            {
                throw new Exception("未注入远程过程调用的实现！", ex);
            }
        }

        /// <summary>
        /// 创建服务代理
        /// </summary>
        /// <param name="proxyType">代理类型</param>
        /// <returns>服务代理实例</returns>
        public object CreateProxy(Type proxyType)
        {
            try
            {
                var iType = ECommon.Components.ObjectContainer.Resolve(proxyType);
                return iType;
            }
            catch (Exception ex)
            {
                throw new Exception("未注入远程过程调用的实现！", ex);
            }
        }


    }
}